<?php

/* Settings.php
 *
 * (C) 2012, StaySimple CMS team.
 *
 * This file is part of StaySimple.
 * http://code.google.com/p/stay-simple-cms/
 *
 * StaySimple is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * StaySimple is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with StaySimple.  If not, see <http://www.gnu.org/licenses/>.
 */

class Settings extends Administration {

    public function __construct() {
        parent::__construct();

        $this->validateUser();
    }

    /**
     * Shows settings form.
     * 
     * @param array $params The options array is ignored.
     */
    public function start($params = array()) {
        $config = Config::getInstance();

        $settings = (object) array(
                    'site' => (object) array(
                        'home' => $config->get('site.home'),
                        'name' => $config->get('site.name'),
                        'theme' => $config->get('site.theme'),
                        'hideindex' => $config->get('site.hideindex')
                    ),
                    'system' => (object) array(
                        'path' => $config->get('system.path'),
                        'theme' => $config->get('system.theme'),
                        'updateinterval' => $config->get('system.updateinterval')
                    ),
                    'locale' => (object) array(
                        'language' => $config->get('locale.language'),
                        'shortdateformat' => $config->get('locale.shortdateformat'),
                        'longdateformat' => $config->get('locale.longdateformat'),
                        'timeformat' => $config->get('locale.timeformat')
                    ),
                    'email' => (object) array(
                        'email' => $config->get('email.email'),
                        'usesmtp' => $config->get('email.usesmtp'),
                        'smtp' => (object) array(
                            'host' => $config->get('email.smtp.host'),
                            'port' => $config->get('email.smtp.port'),
                            'user' => $config->get('email.smtp.username'),
                            'pass' => $config->get('email.smtp.password'),
                            'prefix' => $config->get('email.smtp.prefix')
                        ),
                        'sendhtml' => $config->get('email.html'),
                    ),
                    'editing' => (object) array(
                        'toolbar' => $config->get('editing.toolbar')
                    )
        );

        $pages = array();
        $manager = new PageManager();
        $manager->loadAll();
        foreach ($manager->getTopPages() as $p) {
            if ($p->getName() == '404') {
                continue;
            }
            $pages[] = array($p->getName(), $p->getTitle());
        }

        $themes = StaySimpleCMS::app()->listSiteTemplates();

        $devthemes = array();
        foreach (StaySimpleCMS::app()->listAdminTemplates() as $template) {
            $devthemes[] = array($template->getFolder(), $template->getName());
        }
        $languages = StaySimpleCMS::app()->listLanguages();

        $toolbars = array(
            array('tiny', $this->t('STAY_SETTINGS_TOOLBAR_TINY')),
            array('compact', $this->t('STAY_SETTINGS_TOOLBAR_COMPACT')),
            array('normal', $this->t('STAY_SETTINGS_TOOLBAR_NORMAL')),
            array('complete', $this->t('STAY_SETTINGS_TOOLBAR_COMPLETE')),
            array('maxi', $this->t('STAY_SETTINGS_TOOLBAR_MAXI'))
        );

        $prefixes = array(
            array('', ''),
            array('ssl', 'SSL'),
            array('tsl', 'TSL')
        );

        $this->render('settings', array(
            'content' => 'settings',
            'settings' => $settings,
            'toppages' => $pages,
            'themes' => $themes,
            'devthemes' => $devthemes,
            'languages' => $languages,
            'toolbars' => $toolbars,
            'smtpPrefixes' => $prefixes,
            'active' => 'settings',
        ));
    }

    /**
     * Saves the current settings. This method does little to no validation and 
     * relies on the <em>save</em> method of the <em>Config</em> class.
     * 
     * @param array $params The options array is ignored.
     * 
     * @see Config
     */
    public function save($params = array()) {
        if (isset($_POST['Settings'])) {
            $config = Config::getInstance();

            $config->set('site.home', $_POST['home']);
            $config->set('site.name', $_POST['name']);
            $config->set('site.theme', $_POST['siteheme']);
            $config->set('site.hideindex', $_POST['hideindex']);
            $config->set('system.path', $_POST['path']);
            $config->set('system.theme', $_POST['systheme']);

            $config->set('locale.language', $_POST['language']);
            $config->set('locale.shortdateformat', $_POST['shortdateformat']);
            $config->set('locale.longdateformat', $_POST['longdateformat']);
            $config->set('locale.timeformat', $_POST['timeformat']);

            $config->set('system.updateinterval', $_POST['updateinterval']);

            $config->set('email.email', $_POST['email']);
            $config->set('email.usesmtp', isset($_POST['usesmtp']) ? $_POST['usesmtp'] : 0);
            $config->set('email.smtp.username', $_POST['smtpuser']);
            $config->set('email.smtp.password', $_POST['smtppass']);
            $config->set('email.smtp.host', $_POST['smtphost']);
            $config->set('email.smtp.port', $_POST['smtpport']);
            $config->set('email.smtp.prefix', $_POST['smtpprefix']);
            $config->set('email.html', isset($_POST['sendhtml']) ? $_POST['sendhtml'] : 0);

            $config->set('editing.toolbar', $_POST['toolbar']);

            if (!$config->save()) {
                $this->queueMessage(new Message($this->t('STAY_SETTINGS_SAVE_ERROR'), Message::$ERROR));
            } else {
                $this->queueMessage(new Message($this->t('STAY_SETTINGS_SAVE_SUCCESS')));
            }


            if ($_FILES['themefile']['error'] != UPLOAD_ERR_NO_FILE) {
                foreach ($_FILES as $file) {
                    $file = (object) $file;
                    if (!$file->error) {
                        if (($zip = zip_open($file->tmp_name))) {
                            while ($entry = zip_read($zip)) {
                                $filename = THEMEROOT . '/' . zip_entry_name($entry);
                                if (!is_dir(dirname($filename)))
                                    mkdir(dirname($filename), 0777, true);

                                if (zip_entry_filesize($entry)) {
                                    file_put_contents($filename, zip_entry_read($entry, zip_entry_filesize($entry)));
                                }
                            }

                            $this->queueMessage(new Message($this->t('STAY_SETTINGS_THEME_INSTALL_SUCCESS'), Message::$SUCESS));
                        } else {
                            $this->queueMessage(new Message($this->t('STAY_SETTINGS_THEME_FILETYPE'), Message::$ERROR));
                        }
                    } else {
                        $this->queueMessage(new Message($this->t('STAY_SETTINGS_THEME_UPLOAD_ERROR'), Message::$ERROR));
                    }
                }
            }
        }

        $this->redirect('settings');
    }

    /**
     * Generates and outputs a complete site backup.
     */
    public function backup() {
        try {
            $file = BackupManager::generateFull();
            header('Content-Description: File Transfer');
            header('Content-Type: application/octet-stream');
            header('Content-Disposition: attachment; filename=backup.' . date('Ymd') . '.zip');
            header('Content-Transfer-Encoding: binary');
            header('Expires: 0');
            header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
            header('Pragma: public');
            header('Content-Length: ' . filesize($file));
            ob_clean();
            flush();
            readfile($file);
        } catch (Exception $e) {
            $this->queueMessage(new Message($this->t('STAY_SETTINGS_BACKUP_ERROR')));
        }

        $this->redirect('settings');
    }

    /**
     * Removes old page backups leaving only one backup per page. The method just 
     * delegates to the <em>BackupManager</em>.
     * 
     * @see BackupManager::deleteOld()
     */
    public function prune() {
        if (!BackupManager::deleteOld()) {
            $this->queueMessage(new Message('There was an error while removing the old backups.', Message::$ERROR));
        } else {
            $this->queueMessage(new Message('Old backups removed successfully.'));
        }
        $this->redirect('settings');
    }

    /**
     * Allows for the upload and automatic installation of plugins.
     */
    public function installTheme() {
        foreach ($_FILES as $file) {
            $file = (object) $file;
            if (!$file->error) {
                if (($zip = zip_open($file->tmp_name))) {
                    while ($entry = zip_read($zip)) {
                        $filename = THEMEROOT . '/' . zip_entry_name($entry);
                        if (!is_dir(dirname($filename)))
                            mkdir(dirname($filename), 0777, true);

                        if (zip_entry_filesize($entry)) {
                            file_put_contents($filename, zip_entry_read($entry, zip_entry_filesize($entry)));
                        }
                    }

                    $this->queueMessage(new Message($this->t('STAY_SETTINGS_THEME_INSTALL_SUCCESS'), Message::$SUCESS));
                } else {
                    $this->queueMessage(new Message($this->t('STAY_SETTINGS_THEME_FILETYPE'), Message::$ERROR));
                }
            } else {
                $this->queueMessage(new Message($this->t('STAY_SETTINGS_THEME_UPLOAD_ERROR'), Message::$ERROR));
            }
        }
        $this->redirect('settings');
    }

    /**
     * Allows the preview of different themes using the fancybox jQuery plugin.
     * This method will process and return a view with all the information for 
     * the requested theme.
     * 
     * @param type $params The only used parameter is the folder name for the 
     * current theme, present in $params[0].
     * 
     * @return string The processed view.
     */
    public function previewTheme($params = array()) {

        $content = '<p>' . $this->t('SETTINGS_PREVIEW_THEME_INVALID') . '</p>';
        if (isset($params[0])) {
            $file = THEMEROOT . '/' . $params[0] . '/theme.xml';
            if (is_file($file)) {
                $file = new XMLFile($file);

                $screenshot = $this->getView()->getAssetLink('images/noimage.png', 'ui');
                if (is_file(THEMEROOT . '/' . $params[0] . '/' . strval($file->screenshot))) {
                    $screenshot = $this->getView()->getAssetLink(strval($file->screenshot), $params[0]);
                }

                $templates = array();
                if ($file->templates) {
                    foreach ($file->templates as $tp) {
                        $templates[] = strval($tp->title);
                    }
                }
                if (count($templates)) {
                    $templates = $this->t('STAY_SETTINGS_PREVIEW_THEME_NO_TEMPLATES');
                } else {
                    $templates = implode('&nbsp;', $templates);
                }

                //$selectUrl = $this->getView()->createUrl('settings/selecttheme/' . );

                $needles = array(
                    '{THEME_NAME}',
                    '{USE_LINK_TITLE}',
                    '{SCREENSHOT_IMG}',
                    '{NAME_TITLE}',
                    '{THEME_NAME}',
                    '{AUTHOR_TITLE}',
                    '{THEME_AUTHOR}',
                    '{TEMPLATES_TITLE}',
                    '{THEME_TEMPLATES}',
                    '{URL_LINK}',
                    '{URL_TITLE}',
                    '{DESC_TITLE}',
                    '{THEME_DESC}',
                    '{MINVERSION_TITLE}',
                    '{THEME_MINVERSION}'
                );

                $values = array(
                    $params[0],
                    $this->t('STAY_SETTINGS_PREVIEW_THEME_USE_THEME'),
                    $screenshot,
                    $this->t('STAY_SETTINGS_PREVIEW_THEME_DSC_NAME'),
                    strval($file->name),
                    $this->t('STAY_SETTINGS_PREVIEW_THEME_DSC_AUTHOR'),
                    strval($file->author),
                    $this->t('STAY_SETTINGS_PREVIEW_THEME_DSC_TEMPLATES'),
                    $templates,
                    strval($file->url->link),
                    strval($file->url->title),
                    $this->t('STAY_SETTINGS_PREVIEW_THEME_DSC_DSC'),
                    strval($file->description),
                    $this->t('STAY_SETTINGS_PREVIEW_THEME_MINVERSION_DSC'),
                    strval($file->minversion)
                );

                $content = str_replace($needles, $values, file_get_contents(
                                THEMEROOT . '/' . Config::getInstance()->get('system.theme') . '/_preview.theme.php')
                );
            }
        }

        echo $content;
    }

    /* public function selectTheme($params = array()) {
      if (isset($params[0])) {
      $this->queueMessage(new Message($this->t('')));
      } else {
      $this->queueMessage(new Message($this->t(''), Message::$ERROR));
      }
      } */
}